﻿using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
using Antlr.StringTemplate;
using System.IO;

class Property {
    internal enum Type {
        Bool = 0, Int, Float, String, Vector2, Vector3, Vector4, 
        Rect, Color, Object, Enum, Other
    };

    private string[] types = {
        "bool", "int", "float", "string", "Vector2", "Vector3", "Vector4",
        "Rect", "Color", "Object", "Enum", "Other"
    };

    public Property(string name, Property.Type proptype) {
        this.name = name;
        this.proptype = proptype;
    }

    public string name;
    public Property.Type proptype;

    string GetProptype() {
        return types[(int)proptype];
    }

    string GetProptypeCamel() {
        return types[(int)proptype].Substring(0, 1).ToUpper() + 
            types[(int)proptype].Substring(1);
    }

    string GetNameCamel() {
        return name.Substring(0, 1).ToUpper() + name.Substring(1);
    }

    bool isEnum() {
        return proptype == Type.Enum;
    }

    bool isBool() {
        return proptype == Type.Bool;
    }

    bool isString() {
        return proptype == Type.String;
    }

    bool isOther() {
        return proptype == Type.Other;
    }
}

//View State Behaviour Pattern  
public class VSBPatternGen : EditorWindow {
    private string className = "";
    private List<Property> properties;

    private int propertyCount {
        get { return properties.Count; }
        set {
            if (value <= 0) {
                return;
            }

            if (value > 100) {
                Debug.LogError("More than a hundred properties????" + 
                    " you have some serious design problems buddy.");
                return;
            }

            if (value > properties.Count) {
                int toAdd = value - properties.Count;
                for (int i = 0; i < toAdd; i++) {
                    properties.Add(new Property("", Property.Type.Other));
                }
            }
            else if (value < properties.Count) {
                int toDelete = properties.Count - value;
                for (int i = 0; i < properties.Count && toDelete > 0; i++) {
                    if (properties[i].name == "") {
                        properties.Remove(properties[i--]);
                        toDelete--;
                    }
                }
            }
        }
    }

    private bool createView = true;
    private bool createState = true;
    private bool createBehaviour = true;
    private bool createStateEditor = true;

    private Vector2 scrollVec = new Vector2(0, 0);
    GUILayoutOption[] fcopt = { GUILayout.Width(125) };
    GUILayoutOption[] nmopt = { GUILayout.Width(175) };

    [MenuItem("Assets/Create/VSBPattern")]
    static void Init()
    {
        // Get existing open window or if none, make a new one:
        VSBPatternGen window = (VSBPatternGen)EditorWindow
            .GetWindow(typeof(VSBPatternGen));
        window.Show();
    }

    public VSBPatternGen()
    {
		properties = new List<Property>();
		propertyCount = 1;
    }

    void OnGUI()
    {
        className = EditorGUILayout.TextField("Component name", className, nmopt);
        propertyCount = EditorGUILayout.IntField("Field count", propertyCount, fcopt);
        scrollVec = EditorGUILayout.BeginScrollView(scrollVec);

        for (int i = 0; i < properties.Count; i++) {
            EditorGUILayout.BeginHorizontal();
            properties[i].name = EditorGUILayout.TextField(
                "Name", properties[i].name, nmopt);
            properties[i].proptype = (Property.Type)EditorGUILayout.EnumPopup(
                (System.Enum)properties[i].proptype);
            EditorGUILayout.EndHorizontal();
        }

        EditorGUILayout.EndScrollView();

        createView = EditorGUILayout.Toggle("Create view", createView);
        createState = EditorGUILayout.Toggle("Create state", createState);
        createBehaviour = EditorGUILayout.Toggle("Create behaviour", createBehaviour);
        createStateEditor = EditorGUILayout.Toggle("Create state editor", createStateEditor);
        if (GUILayout.Button("Generate")) {
            StreamReader sr = File.OpenText(RueexPaths.paths[(int)RueexPaths.AvailablePaths.Templates] + "VSBPattern.stg");
            StringTemplateGroup stg = new StringTemplateGroup(sr);

            if (createView)
                Generate(stg, RueexPaths.paths[(int)RueexPaths.AvailablePaths.Views], "View");
            if (createState)
                Generate(stg, RueexPaths.paths[(int)RueexPaths.AvailablePaths.States], "State");
            if (createBehaviour)
                Generate(stg, RueexPaths.paths[(int)RueexPaths.AvailablePaths.Behaviours], "Behaviour");
            if (createStateEditor)
                Generate(stg, RueexPaths.paths[(int)RueexPaths.AvailablePaths.StateEditors], "StateEditor");

            sr.Close();
        }
    }

    void CreateDirectories() {
        foreach (string path in RueexPaths.paths)
            if (!Directory.Exists(path))
                Directory.CreateDirectory(path);
    }

    void Generate(StringTemplateGroup stg, string path, string name) {
        CreateDirectories();
        if (File.Exists(path + className + name + ".cs"))
            return;

        StringTemplate st = stg.GetInstanceOf(name.ToLower());

        st.SetAttribute("name", className);

        foreach (Property p in properties) {
            if (!p.name.Equals(""))
                st.SetAttribute("properties", p);
        }

        File.WriteAllText(path + className + name + ".cs",
            st.ToString());
    }
}
